#include "ddUtilities.h"

ddUtilities::ddUtilities(void)
{
}

ddUtilities::~ddUtilities(void)
{
}

int ddUtilities::ddFillSurface(LPDIRECTDRAWSURFACE7 lpdds, int color)
{
	DDBLTFX ddbltfx; // this contains the DDBLTFX structure

	// clear out the structure and set the size field 
	INIT_DDRAW(ddbltfx);

	// set the dwfillcolor field to the desired color
	ddbltfx.dwFillColor = color; 

	// ready to blt to surface
	lpdds->Blt(NULL,       // ptr to dest rectangle
			   NULL,       // ptr to source surface, NA            
			   NULL,       // ptr to source rectangle, NA
			   DDBLT_COLORFILL | DDBLT_WAIT,   // fill and wait                   
			   &ddbltfx);  // ptr to DDBLTFX structure

	// return success
	return(1);
}

LPDIRECTDRAWCLIPPER ddUtilities::ddAttachClipper(LPDIRECTDRAWSURFACE7 lpdds,
												 int numRects,
												 LPRECT clipList)

{
	LPDIRECTDRAWCLIPPER lpddclipper;
	LPRGNDATA rgnData;

	if (FAILED(lpdd7->CreateClipper(0, &lpddclipper, NULL)))
	{
		return(NULL);
	}

	rgnData = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+numRects*sizeof(RECT));
	memcpy(rgnData->Buffer, clipList, numRects*sizeof(RECT));

	rgnData->rdh.dwSize = sizeof(RGNDATAHEADER);
	rgnData->rdh.iType = RDH_RECTANGLES;
	rgnData->rdh.nCount = numRects;
	rgnData->rdh.nRgnSize = numRects*sizeof(RECT);

	rgnData->rdh.rcBound.left	= 64000;
	rgnData->rdh.rcBound.top	= 64000;
	rgnData->rdh.rcBound.right	= -64000;
	rgnData->rdh.rcBound.bottom = -64000;

	for (int i = 0; i < numRects; i++)
	{
		if (clipList[i].left < rgnData->rdh.rcBound.left)
			rgnData->rdh.rcBound.left = clipList[i].left;

		if (clipList[i].right > rgnData->rdh.rcBound.right)
			rgnData->rdh.rcBound.right = clipList[i].right;

		if (clipList[i].top < rgnData->rdh.rcBound.top)
			rgnData->rdh.rcBound.top = clipList[i].top;

		if (clipList[i].bottom > rgnData->rdh.rcBound.bottom)
			rgnData->rdh.rcBound.bottom = clipList[i].bottom;
	}

	if (FAILED(lpddclipper->SetClipList(rgnData, 0)))
	{
		free(rgnData);
		return(NULL);
	}
	if (FAILED(lpdds->SetClipper(lpddclipper)))
	{
		free(rgnData);
		return(NULL);
	}

	free(rgnData);
	return(lpddclipper);
}

LPDIRECTDRAWSURFACE7 ddUtilities::ddCreateSurface(int width, int height, int memFlags, bool colorKey)
{
	DDSURFACEDESC2 ddsd;
	LPDIRECTDRAWSURFACE7 lpdds;

	INIT_DDRAW(ddsd);

	ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;

	ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | memFlags;

	ddsd.dwHeight = height;
	ddsd.dwWidth = width;

	if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds, NULL)))
		return(NULL);

	if (colorKey)
	{
		DDCOLORKEY colorKey;
		colorKey.dwColorSpaceHighValue = 0;
		colorKey.dwColorSpaceLowValue = 0;

		lpdds->SetColorKey(DDCKEY_SRCBLT, &colorKey);
	}

	return(lpdds);
}

int ddUtilities::buildSurface(void *params, int numParms)
{
	LPDDSCAPS2 lpddscaps = NULL;
	INIT_DDRAW(ddsd);

	ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
	ddsd.dwBackBufferCount = 1;
	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_VIDEOMEMORY;

	if (FAILED(lpdd7->CreateSurface(&ddsd, &lpddsprimary, NULL)))
	{
		return(-1);
	}

	ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_VIDEOMEMORY;

	if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))
		return(-1);

	return(0);
}